package com.huanke.iot.api.service.newapp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Maps;
import com.huanke.iot.api.controller.h5.req.ChildDeviceRequest;
import com.huanke.iot.api.controller.newapp.model.*;
import com.huanke.iot.api.service.device.basic.DeviceHighService;
import com.huanke.iot.api.service.device.basic.DeviceModelService;
import com.huanke.iot.api.service.device.basic.DeviceService;
import com.huanke.iot.base.commpent.OssUploadTool;
import com.huanke.iot.base.dao.device.scene.DeviceSceneMapper;
import com.huanke.iot.base.dao.device.typeModel.DeviceModelFileMapper;
import com.huanke.iot.base.po.device.DevicePo;
import com.huanke.iot.base.po.device.model.DeviceModelFilePo;
import com.huanke.iot.base.po.device.scene.DeviceScenePo;
import com.huanke.iot.base.po.device.typeModel.DeviceModelPo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
@Slf4j
public class NewAppDeviceService {

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private DeviceHighService deviceHighService;

    @Autowired
    private DeviceModelService deviceModelService;


    @Autowired
    private DeviceModelFileMapper deviceModelFileMapper;

    @Autowired
    private DeviceSceneMapper deviceSceneMapper;

    @Autowired
    private OssUploadTool ossUploadTool;
    public List<NewAppChildDeviceDTO> queryChildDeviceList(String deviceId) {

        List<DevicePo> childDeviceList = deviceService.queryChildDeviceList(Integer.valueOf(deviceId));
        List<NewAppChildDeviceDTO> newAppChildDeviceDTOS = childDeviceList.stream()
                .map(

                        devicePo -> {
                            NewAppChildDeviceDTO deviceDTO = new NewAppChildDeviceDTO();
                            deviceDTO.setDeviceName(devicePo.getName());
                            deviceDTO.setDeviceChildId(devicePo.getId());
                            deviceDTO.setChildId(devicePo.getChildId());
                            //获取型号码
                            DeviceModelPo deviceModelPo=deviceModelService.selectById(devicePo.getModelId());
                            if (deviceModelPo !=null) {
                                if(deviceModelPo.getNo()!=null) {
                                    Integer ino = Integer.valueOf(deviceModelPo.getNo(), 16);
                                    deviceDTO.setNo(ino);
                                }
                                deviceDTO.setDeviceModelName(deviceModelPo.getName());
                            }
                            deviceDTO.setDeviceModelId(devicePo.getModelId());
                            return deviceDTO;
                        }
                ).collect(Collectors.toList());

        return newAppChildDeviceDTOS;
    }

    public List<DeviceModelPo> queryAllModels(String modelId) {
        if(StringUtils.isNotEmpty(modelId)){
            DeviceModelPo deviceModelPo = deviceModelService.selectById(Integer.valueOf(modelId));
            if(deviceModelPo != null){
                return Lists.newArrayList(deviceModelPo);
            }
        }
        List<DeviceModelPo> deviceModelPos = deviceModelService.queryAllModels();

        return deviceModelPos;
    }

    public Boolean updateDeviceInfo(DeviceUpdateInfoDTO deviceUpdateInfoDTO) {

        DevicePo parentPo = deviceService.selectById(deviceUpdateInfoDTO.getDeviceId());

        if(parentPo == null){
           return false;
        }
        List<DevicePo> childList = deviceService.queryChildDeviceList(deviceUpdateInfoDTO.getDeviceId());

        Map<String,DevicePo> devicePoMap = Maps.newHashMap();

        childList.forEach(devicePo -> {
            devicePoMap.put(devicePo.getChildId(), devicePo);
        });

        for(DeviceUpdateInfoDTO.DeviceChildData deviceChildData : deviceUpdateInfoDTO.getChildDataList()){
            ChildDeviceRequest childDeviceRequest = new ChildDeviceRequest();
            childDeviceRequest.setChildId(deviceChildData.getChildId());
            Integer modelId=null;
            if (deviceChildData.getNo()!=null) {
                //log.info("型号码：0000:"+deviceChildData);
                //log.info("型号码：1111:"+deviceChildData.getNo());
                String no= Integer.toHexString(deviceChildData.getNo());
                //log.info("型号码：2222:"+no);
                modelId = deviceModelService.selectByNo(no).getId(); //通过型号码(整型) 获取 设备型id
            }
            log.info("型号码："+deviceChildData.getNo()+"获取型号id："+modelId);

            if(devicePoMap.containsKey(deviceChildData.getChildId())){
                DevicePo childPo = devicePoMap.get(deviceChildData.getChildId());
                childDeviceRequest.setModelId(modelId);
                deviceHighService.deleteById(childPo.getId());
            }else{
                childDeviceRequest.setModelId(modelId);
            }
            childDeviceRequest.setHostDeviceId(deviceUpdateInfoDTO.getDeviceId());
            childDeviceRequest.setDeviceName(deviceChildData.getName());
            //获得主机的IP以及相关地址参数
            childDeviceRequest.setIp(parentPo.getIp()); //用主机的ip
            childDeviceRequest.setMapGps(parentPo.getMapGps()); //用主机的经纬度
            childDeviceRequest.setLocation(parentPo.getLocation());//用主机的所在位置
            try {
                deviceHighService.addChildDevice(childDeviceRequest);
            } catch (Exception e) {

            }
        }

        return true;
    }


    public Boolean deleteChild(DeleteChildDTO deleteChildDTO) {
        List<DevicePo> childList = deviceService.queryChildDeviceList(deleteChildDTO.getHostDeviceId());
        for(String childIdStr : deleteChildDTO.getChildIdList()) {
            Optional<DevicePo> optionalPo = childList.stream().filter(devicePo -> devicePo.getChildId().equalsIgnoreCase(childIdStr))
                    .findAny();
            if (optionalPo.isPresent()) {
                DevicePo devicePo = optionalPo.get();
                deviceHighService.deleteById(devicePo.getId());
            }
        }

        return Boolean.TRUE;
    }

    public Boolean uploadModelConfig(Integer modelId, MultipartFile file) {
        try {
            if(file == null){
                return Boolean.FALSE;
            }

            List<DeviceModelFilePo> deviceModelFilePos = deviceModelFileMapper.queryFileListByModelId(Lists.newArrayList(modelId));
            String sourceName = file.getOriginalFilename();
            String generateFile = ossUploadTool.addFile("modelconfig", file.getBytes());
            Optional<DeviceModelFilePo> optional =
                    deviceModelFilePos.stream().filter(d -> sourceName.equalsIgnoreCase(d.getFileName())).findFirst();
            DeviceModelFilePo deviceModelFilePo;
            if(optional.isPresent()){
                DeviceModelFilePo updatePo = new DeviceModelFilePo();
                updatePo.setLastUpdateTime(System.currentTimeMillis());
                updatePo.setFilePath("https://modelconfig.oss-cn-hangzhou.aliyuncs.com/"+generateFile);
                updatePo.setId(optional.get().getId());
                deviceModelFileMapper.updateById(updatePo);

            }else{
                deviceModelFilePo =   new DeviceModelFilePo();
                deviceModelFilePo.setModelId(modelId);
                deviceModelFilePo.setFileName(sourceName);
                deviceModelFilePo.setFilePath("https://modelconfig.oss-cn-hangzhou.aliyuncs.com/"+generateFile);
                deviceModelFilePo.setCreateTime(System.currentTimeMillis());
                deviceModelFileMapper.insert(deviceModelFilePo);
            }


        }catch (Exception e){

        }

        return Boolean.TRUE;
    }

    public void fillModelFile(List<DeviceModelDTO> deviceModelDTOS) {
        List<Integer> modelIds = deviceModelDTOS.stream().map(d->d.getModelId()).collect(Collectors.toList());

        List<DeviceModelFilePo> deviceModelFilePos = deviceModelFileMapper.queryFileListByModelId(modelIds);


        for(DeviceModelDTO deviceModelDTO : deviceModelDTOS){
            List<DeviceModelFilePo> tmpFilePos = deviceModelFilePos.stream().filter(d->d.getModelId().equals(deviceModelDTO.getModelId()))
                    .collect(Collectors.toList());

            List<DeviceModelDTO.ConfigDTO> configDTOS = tmpFilePos.stream().map(
                    d->{
                        DeviceModelDTO.ConfigDTO configDTO = new DeviceModelDTO.ConfigDTO();
                        configDTO.setConfigId(d.getId());
                        configDTO.setFilePath(d.getFilePath());
                        configDTO.setFileName(d.getFileName());
                        configDTO.setFileImg(d.getFileImg());
                        return configDTO;
                    }
            ).collect(Collectors.toList());

            deviceModelDTO.setConfigDTOS(configDTOS);
        }
    }


    public Boolean addModifyScene(DeviceSceneDTO deviceSceneDTO) {
        Integer hostDeviceId = deviceSceneDTO.getHostDeviceId();
        DevicePo devicePo = deviceService.selectById(hostDeviceId);

        if(devicePo == null && devicePo.getHostDeviceId() > 0){
            return  false;
        }
        //判断名称是否重复
        String sceneName = deviceSceneDTO.getSceneName();
        DeviceScenePo deviceScenePo = deviceSceneMapper.selectByName(hostDeviceId, sceneName);
        if(deviceScenePo != null){
            log.error("情景模式名称重复 deviceId->{},sceneName->{}", hostDeviceId, sceneName);
            return false;
        }
        DeviceScenePo addScenePo = new DeviceScenePo();
        addScenePo.setCreateTime(System.currentTimeMillis());
        addScenePo.setSceneName(deviceSceneDTO.getSceneName());
        addScenePo.setSceneValue(JSON.toJSONString(deviceSceneDTO.getChildSceneList()));
        addScenePo.setDeviceId(hostDeviceId);
        deviceSceneMapper.insert(addScenePo);
        return Boolean.TRUE;
    }

    public DeviceSceneListDTO getSceneById(Integer deviceId) {
        DeviceSceneListDTO deviceSceneListDTO = new DeviceSceneListDTO();
        List<DeviceSceneListDTO.scene> sceneList = new ArrayList<>();
        deviceSceneListDTO.setHostDeviceId(deviceId);
        List<DeviceScenePo> deviceScenePoList = deviceSceneMapper.findByDeviceId(Integer.valueOf(deviceId));
        for (DeviceScenePo deviceScenePo : deviceScenePoList) {
            DeviceSceneListDTO.scene scene = new DeviceSceneListDTO.scene();
            scene.setSceneName(deviceScenePo.getSceneName());
            List<DeviceSceneListDTO.sceneDTO> sceneDTOList = JSONArray.parseArray(deviceScenePo.getSceneValue(), DeviceSceneListDTO.sceneDTO.class);
            scene.setChildSceneList(sceneDTOList);
            sceneList.add(scene);
        }
        deviceSceneListDTO.setSceneList(sceneList);
        return deviceSceneListDTO;
    }

    public Boolean deleteFile(List<Integer> configIds) {
        deviceModelFileMapper.batchDelete(configIds);
        return Boolean.TRUE;
    }


    public Boolean deleteScene(DeleteSceneDTO deleteSceneDTO) {
        deviceSceneMapper.deleteByDeviceIdAndName(deleteSceneDTO.getHostDeviceId(), deleteSceneDTO.getSceneNameList());
        return Boolean.TRUE;
    }
}
